// Copyright 2020 Apulis Technology Inc. All rights reserved.

package configs

import (
	"fmt"
	"net"
	"strings"

	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

var Config AppConfig

type AppConfig struct {
	DebugModel bool
	Portal     PortalConfig
	Log        LogConfig
	Db         DbConfig
	Rabbitmq   Rabbitmq
	Cluster    Cluster
	Relevant   Relevant
}

type Rabbitmq struct {
	Host                string
	Port                string
	UserName            string
	Password            string
	Vhost               string
	ExchangeJs          string
	ExchangeApsc        string
	TopicApedgeNode     string
	TopicModelTransform string
	QueueApedgeNode     string
	QueueModelTransform string
	QueueJs             string
}

type Base struct {
	ModId string
	Url   string
}

type DbConfig struct {
	Username     string
	Password     string
	Host         string
	Port         int
	Database     string
	Sslmode      string
	MaxOpenConns int
	MaxIdleConns int
}

type HttpConfig struct {
	Address string
	Port    int
	Enable  bool
}

type PortalConfig struct {
	Http HttpConfig
}

type LogConfig struct {
	Level     logrus.Level
	WriteFile bool
	FileDir   string
	FileName  string
}

type Cluster struct {
	CACrtPath       string
	CAKeyPath       string
	CAEncryptPass   string
	CertDuration    int
	DownloadAddress string
	Domain          string
	EdgeImage       string
	EdgeImageTag    string
	Ip              string
	Host            string
}

type Relevant struct {
	Service            Service
	NodeInfo           NodeInfo
	Image              Image
	Jwt                Jwt
	ModId              string
	ModelMaxNumPerTask int64
	ResourceLabel      string
	ApedgePublicKey    string
}

type Service struct {
	ModelFactorySvc     string
	InferenceBackendSvc string
	AomSvc              string
	FileServerSvc       string
	APSC                string
}

type NodeInfo struct {
	NodeType     []string
	NodeArchType []string
}

type Jwt struct {
	SignAlgorithm string
	SecretKey     string
	PublicKey     string
}

type Image struct {
	InitContainer               string
	InitContainerTag            string
	NpuInferImage               string
	NpuInferImageTag            string
	GpuInferTransformerImage    string
	GpuInferTransformerImageTag string
	TritonImage                 string
	TritonImageTag              string
}

func InitConfig(configFile string, config *AppConfig) {
	viper.SetConfigFile(configFile)

	// set default
	viper.SetDefault("DebugModel", false)

	err := viper.ReadInConfig()
	if err != nil {
		panic(fmt.Errorf("fatal error read config file: %s ", err))
	}

	if err := viper.Unmarshal(&config); err != nil {
		panic(fmt.Errorf("fatal error unmarshal config file: %s ", err))
	}
	config.Relevant.Service.APSC = "aom-backend"
	// 获取到主机host 可能为域名可能为ip地址
	config.Cluster.Host = GetHost(config.Cluster.Ip)
	// 根据host 来确定 域名
	config.Cluster.Domain = GetDomain(config)

	fmt.Printf("Portal config = %+v\n", config.Portal)
	fmt.Printf("Db config = %+v\n", config.Db)
	fmt.Printf("Rabbitmq config = %+v\n", config.Rabbitmq)
	fmt.Printf("Cluster config = %+v\n", config.Cluster)
	fmt.Printf("RelevantSvc config = %+v\n", config.Relevant)
}

// 解析出host 可能是域名可能是ip
func GetHost(s string) string {
	if s == "" {
		return ""
	}
	s1List := strings.Split(s, "//")
	if len(s1List) != 2 {
		return ""
	}
	s2list := strings.Split(s1List[1], ":")
	if len(s2list) != 2 {
		return ""
	} else {
		return s2list[0]
	}
}

func GetDomain(config *AppConfig) string {
	var domain string

	if config.Cluster.Host != "" {
		address := net.ParseIP(config.Cluster.Host)
		if address == nil {
			// 域名
			domain = config.Cluster.Host
		} else {
			// ip
			domain = config.Cluster.Domain
		}
	} else {
		domain = config.Cluster.Domain
	}
	return domain
}
